 package dbhandelling;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.HashMap;

public abstract class Crude {
	
	
	
	
	// Insert
	public  void insert(String tableName,String[]values)
	{
		Connection con=Connections.getMyConnection();
		
		values=this.manageStringColums(tableName,values);
		
		String value="";
		for(int k =0;k<values.length;k++)
		{
			if(k==values.length-1)
				value=value+values[k];
			else
				value=value+values[k]+",";
		}
		
		String sql="insert into "+ tableName+" values( "+value +" )";
		
		try {
			Statement smt=con.createStatement();
			smt.executeUpdate(value);
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			System.out.println(value);
			e.printStackTrace();
		}
		
			
	}
	
	
	
	
	/*
	 * Incomplete method
	 */
	public  Object[] retreiveArrayOnCondition(String tableName,String conditionField,String conditionValue) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException
	{
		Connection con=Connections.getMyConnection();
		String sql=null;
		try {
			Statement st=con.createStatement();
			
			if(manageString(tableName,conditionValue))
				conditionValue="'"+conditionValue+"'";
			
		     sql="SELECT *  from "+tableName+" WHERE "+conditionField+" = "+conditionValue;
		     ResultSet rs=st.executeQuery(sql);
		     int count = 0;
		     
		     Constructor constructor=null;
		    
		     while(rs.next())
		    	 count++;
		     
		     Object[]objects=new Object[count];
		     rs=st.executeQuery(sql);
		     try {
				HashMap<Field,Method> hash=this.getFieldMethodPair("invetory.model"+tableName);
				Class clas=Class.forName("invetory.model"+tableName);
				 constructor =clas.getConstructor(new Class[]{});
				 //from this constructor create Object type obj
				 //start getting fields from hash ,from the data type of the field decide
				 // by using if else which method of rs is to be called.
				 //from that same field get corresponding setter methhod.
				 // on obj invoke that method with argument from rs
				
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		     
		     while(rs.next())
		     {
		    	Object temp=constructor.newInstance();
		    	
		    	
		     }
		     
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			System.out.println(sql);
			e.printStackTrace();
		}
		
		return null;
		
	}
	
	public  Object retreive(String tableName,String conditionField,String conditionValue)
	{
		
		
		return conditionValue;
		
	}
	
	
	//delete
	public  void delete(String tableName,String conditionField,String conditionValue)
	{
		Connection con=Connections.getMyConnection();
		
		String sql=null;
		try {
			Statement st=con.createStatement();
			
			
			
			if(manageString(tableName,conditionValue))
				conditionValue="'"+conditionValue+"'";
		     sql=" DELETE FROM "+tableName+" where "+conditionField+ " = " +conditionValue;
		     st.execute(sql);
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			System.out.println(sql);
			e.printStackTrace();
		}
		
		
	}
	
	//update
	
	public  void update(String tableName,String requiredField,String requiredValue,String conditionField,String conditionValue)
	{
		Connection con=Connections.getMyConnection();
		String sql=null;
		try {
			Statement st=con.createStatement();
			
			if(manageString(tableName,requiredField))
				requiredValue="'"+requiredValue+"'";
			
			if(manageString(tableName,conditionField))
				conditionValue="'"+conditionValue+"'";
		    
			sql="UPDATE "+tableName+" set "+requiredField+" = "+ requiredValue + " WHERE "+
			
			conditionField+ " = "+conditionValue;
		     st.execute(sql);
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			System.out.println(sql);
			e.printStackTrace();
		}
		
	}
	
	
	//Data type returning method
	public   boolean manageString(String tableName,String attributeName)
	{
		                String type=null;
			           try {
						
			        	   Class c=Class.forName(tableName);
			        	   Field f=c.getDeclaredField(attributeName);
			        	   
			        	  type=f.getType().toString();
						
			        	   if(type.contains("String"))
			        		   return true;
					} 
			           
			       catch (Exception e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
			           
			return false;
		
	}
	
	
	
	
	
	
	
	
	
	private String[] manageStringColums(String tableName,String[]values)
	{
		Connection conn=Connections.getMyConnection();
		Statement st;
		String[]data=null;
		try {
			st = conn.createStatement();
			
			ResultSet rset = st.executeQuery("SELECT * FROM \""+tableName+"\"");
			
			ResultSetMetaData md = rset.getMetaData();
			
			String temp;
			int k=0;
			
			for (int i=1; i<=md.getColumnCount(); i++)
			{
			    temp=md.getColumnClassName(i);
			    
			    if(temp.contains("String"))
			    {
			    	values[k]="'"+values[k]+"'";
			    	k++;
			    }
			}
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
			
		
		return values;
		
		
	
	}
	
	private HashMap<Field,Method> getFieldMethodPair(String classname) throws Exception
	{
		Class t = Class.forName("inventory.model."+classname);
		
		Field[] f=t.getDeclaredFields();
		
		Method[] methods=t.getMethods();
		
		Method[] setter=null;
		int count=0;
		for(Method temp:methods)
		{
		   if(isSetter(temp))
			   count++;
		}
		setter=new Method[count];
		int i=0;
		for(Method temp:methods)
			   if(isSetter(temp))
			   {
				   
				   setter[i]=temp;
				   i++;
			   }
		
		
		HashMap<Field, Method> hm=new HashMap<Field, Method>();
		
		String tempField,tempMethod;
		
		for( i=0;i<f.length;i++)
		{
			
			for(int j=0;j<setter.length;j++)
			{
				
				tempField=f[i].getName().toLowerCase();
				tempMethod=setter[j].getName().toLowerCase();
				
				if(tempMethod.endsWith(tempField))
				{
					
					hm.put(f[i], setter[j]);
					break;
				}
			}
		}
		return hm;
	}

	
	
	
	
	
	
	
	
	
	
	public static boolean isGetter(Method method){
		  if(method.getName().startsWith("get")) return true;
		  if(method.getParameterTypes().length != 0)   return false;  
		  if(void.class.equals(method.getReturnType())) return false;
		      return true;
		}
	
	public static boolean isSetter(Method method){
		  if(!method.getName().startsWith("set")) return false;
		  if(method.getParameterTypes().length != 1) return false;
		  return true;
		}


}
